package pl.gettoknowme.mobile.android.services.calls;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import pl.gettoknowme.mobile.android.services.calls.CallLogEntry.CallType;

/**
 * Analizator połączeń telefonicznych
 * @author Michał Kołodziejski
 */
public class CallLogAnalyzer {

    public CallLogAnalyzer() {
    }
    
    /**
     * Zlicza sumaryczny czas połączeń każdego typu
     * @param callLogs historia połączeń z podziałem na typy rozmów
     * @return sumaryczny czas połączeń każdego typu
     */
    public Map<CallType, Long> getTotalCallsTime(Map<CallType, List<CallLogEntry>> callLogs){
        Map<CallType, Long> resultMap = new HashMap<CallType, Long>();
        
        for(CallType callType : callLogs.keySet()){
            long totalSeconds = 0l;
            for(CallLogEntry logEntry : callLogs.get(callType)){
                totalSeconds += logEntry.getSeconds();
            }
            
            resultMap.put(callType, Long.valueOf(totalSeconds));
        }
        
        return resultMap;
    }
    
    /**
     * Zwraca listę z wyliczoną sumą długości rozmów z każdym numerem.
     * Lista jest posortowana malejąco względem sumarycznego czasu rozmów.
     * @param callLogs historia połączeń z podziałem na typy rozmów
     * @return lista z wyliczoną sumą długości rozmów z każdym numerem
     */
    public List<CallSingleNumberStats> getGroupedByNumberTotalCallTimes(Map<CallType, List<CallLogEntry>> callLogs){
        Map<String, CallSingleNumberStats> numbersMap = new HashMap<String, CallSingleNumberStats>();

        for(CallType callType : callLogs.keySet()){
            for(CallLogEntry logEntry : callLogs.get(callType)){
                CallSingleNumberStats numberStats = numbersMap.get(logEntry.getNumber());
                
                if(numberStats != null){
                    if(CallType.INCOMING.equals(logEntry.getCallType())){
                        numberStats.setIncomingCallsNumber(numberStats.getIncomingCallsNumber() + 1);
                        numberStats.setIncomingCallsSeconds(numberStats.getIncomingCallsSeconds() + logEntry.getSeconds());
                        
                    } else if(CallType.OUTGOING.equals(logEntry.getCallType())){
                        numberStats.setOutgoingCallsNumber(numberStats.getOutgoingCallsNumber() + 1);
                        numberStats.setOutgoingCallsSeconds(numberStats.getOutgoingCallsSeconds() + logEntry.getSeconds());
                    }
                    
                } else {
                    numberStats = new CallSingleNumberStats();
                    numberStats.setNumberHash(logEntry.getNumber());
                    
                    if(CallType.INCOMING.equals(logEntry.getCallType())){
                        numberStats.setIncomingCallsNumber(1);
                        numberStats.setIncomingCallsSeconds(logEntry.getSeconds());
                        
                    } else if(CallType.OUTGOING.equals(logEntry.getCallType())){
                        numberStats.setOutgoingCallsNumber(1);
                        numberStats.setOutgoingCallsSeconds(logEntry.getSeconds());
                    }
                    
                    // nie było - dodajemy
                    numbersMap.put(numberStats.getNumberHash(), numberStats);
                }
            }
            
        }
        
        List<CallSingleNumberStats> numberStatsList = new ArrayList<CallSingleNumberStats>(numbersMap.values());
        
        Collections.sort(numberStatsList, new Comparator<CallSingleNumberStats>() {
            @Override
            public int compare(CallSingleNumberStats entry1, CallSingleNumberStats entry2) {
                long totalSecondsE1 = entry1.getIncomingCallsSeconds() + entry1.getOutgoingCallsSeconds();
                long totalSecondsE2 = entry2.getIncomingCallsSeconds() + entry2.getOutgoingCallsSeconds();
                
                if(totalSecondsE1 > totalSecondsE2){
                    return -1;
                } else if (totalSecondsE1 == totalSecondsE2){
                    return 0;
                } else {
                    return 1;
                }
            }
        });
        
        return numberStatsList;
    }
}
